import { ContextMenuItem, ContextMenuOptions } from '../../interface';

/**
 * 上下文菜单控制器
 *
 * @export
 * @class ContextMenuController
 */
export class ContextMenuController {
  /**
   * 上下文菜单控制器
   *
   * @author chitanda
   * @date 2021-03-18 11:03:08
   * @private
   * @type {HTMLContextMenuElement}
   */
  private container: HTMLContextMenuElement;

  /**
   * 注册监控事件
   *
   * @author chitanda
   * @date 2021-03-18 09:03:10
   * @private
   */
  private addEvents(): void {
    window.addEventListener('mousedown', this.destroy, { capture: true });
    window.addEventListener('blur', this.destroy, { capture: true });
    window.addEventListener('resize', this.destroy, { capture: true });
  }

  /**
   * 删除监控事件
   *
   * @author chitanda
   * @date 2021-03-18 09:03:34
   * @private
   */
  private removeEvents(): void {
    window.removeEventListener('mousedown', this.destroy, { capture: true });
    window.removeEventListener('blur', this.destroy, { capture: true });
    window.removeEventListener('resize', this.destroy, { capture: true });
  }

  /**
   * 销毁右键菜单
   *
   * @author chitanda
   * @date 2021-03-18 11:03:25
   * @private
   */
  private destroy = (): void => {
    if (this.container?.isHover() === false) {
      this.close();
    }
  };

  /**
   * 打开右键菜单
   *
   * @author chitanda
   * @date 2021-03-18 10:03:38
   * @param {MouseEvent} e
   * @param {ContextMenuItem[]} menus
   * @param {ContextMenuOptions} [ops]
   */
  open(e: MouseEvent, menus: ContextMenuItem[], ops?: ContextMenuOptions): ContextMenuController {
    e.preventDefault();
    e.stopPropagation();
    this.close();
    this.addEvents();
    this.container = document.createElement('context-menu') as any;
    this.container.options = ops;
    this.container.menus = menus;
    document.body.appendChild(this.container as any);
    this.container.addEventListener('didLoad', () => this.show(e));
    return this;
  }

  /**
   * 订阅菜单项点击
   *
   * @author chitanda
   * @date 2021-03-18 15:03:52
   * @param {(item: ContextMenuItem) => void} fn
   */
  click(fn: (item: ContextMenuItem) => void): void {
    if (fn) {
      this.container.addEventListener('itemClick', (e: CustomEvent) => {
        this.close();
        fn(e.detail);
      });
    }
  }

  /**
   * 显示右键菜单
   *
   * @author chitanda
   * @date 2021-03-18 15:03:47
   * @private
   * @param {MouseEvent} e
   */
  private show(e: MouseEvent): void {
    if (this.container) {
      const { offsetWidth, offsetHeight } = this.container;
      const { pageX, pageY } = e;
      let top = 0;
      if (innerHeight - pageY < offsetHeight) {
        top = pageY - offsetHeight;
      } else {
        top = pageY;
      }
      if (top < 0) {
        top = 0;
      }
      let left = 0;
      if (innerWidth - pageX < offsetWidth) {
        left = pageX - offsetWidth;
      } else {
        left = pageX;
      }
      this.container.style.top = top + 'px';
      this.container.style.left = left + 'px';
    }
  }

  /**
   * 关闭右键菜单
   *
   * @author chitanda
   * @date 2021-03-18 11:03:42
   * @private
   */
  private close(): void {
    if (this.container) {
      document.body.removeChild(this.container as any);
      this.container = undefined;
    }
    this.removeEvents();
  }
}
// 导出实例
export const contextMenu = new ContextMenuController();
